/*
   Copyright (c) 2011 Mizar Tools Contributors (mizartools.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
/*  Contributors :
 *	2011-02-04 Marco Riccardi - initial implementation
 *
 */
package org.mizartools.system;

import java.util.ArrayList;

import org.mizartools.utility.SystemHost;


public class Symbols {

	private String articleId;
	
	private int numberOfSymbolG = 0;
	private int numberOfSymbolK = 0;
	private int numberOfSymbolL = 0;
	private int numberOfSymbolM = 0;
	private int numberOfSymbolO = 0;
	private int numberOfSymbolR = 0;
	private int numberOfSymbolU = 0;
	private int numberOfSymbolV = 0;

	private int numberOfSymbolInFileG = 0;
	private int numberOfSymbolInFileK = 0;
	private int numberOfSymbolInFileL = 0;
	private int numberOfSymbolInFileM = 0;
	private int numberOfSymbolInFileO = 0;
	private int numberOfSymbolInFileR = 0;
	private int numberOfSymbolInFileU = 0;
	private int numberOfSymbolInFileV = 0;
	
	private ArrayList<Symbol> symbolList = new ArrayList<Symbol>();

	public Symbols(String articleId){
		this.articleId = articleId;
	}

	public void addSymbol(SymbolKind symbolKind, String symbolToken, String symbolNegativeToken, String symbolPrecedence, boolean isSyntaxToken){
		Symbol symbol = new Symbol(symbolKind, symbolToken, symbolNegativeToken, symbolPrecedence, isSyntaxToken);
		symbolList.add(symbol);
		addToNumber(symbolKind, isSyntaxToken);
	}

	public void addSymbol(int index, SymbolKind symbolKind, String symbolToken, String symbolNegativeToken, String symbolPrecedence, boolean isSyntaxToken){
		Symbol symbol = new Symbol(symbolKind, symbolToken, symbolNegativeToken, symbolPrecedence, isSyntaxToken);
		symbolList.add(index, symbol);
		addToNumber(symbolKind, isSyntaxToken);
	}

	private void addToNumber(SymbolKind symbolKind, boolean isSyntaxToken) {
		switch (symbolKind){
		case G : 
			numberOfSymbolG += 1;
			if (!isSyntaxToken) numberOfSymbolInFileG += 1;
			break;
		case K : 
			numberOfSymbolK += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileK += 1;
			break;
		case L : 
			numberOfSymbolL += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileL += 1;
			break;
		case M : 
			numberOfSymbolM += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileM += 1;
			break;
		case O : 
			numberOfSymbolO += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileO += 1;
			break;
		case R : 
			numberOfSymbolR += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileR += 1;
			break;
		case U : 
			numberOfSymbolU += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileU += 1;
			break;
		case V : 
			numberOfSymbolV += 1; 
			if (!isSyntaxToken) numberOfSymbolInFileV += 1;
			break;
		default : ;
		}
	}
	
	
	/**
	 * @return The articleId of Symbols
	 */
	public String getArticleId() {
		return articleId;
	}

	/**
	 * @return The number of structure symbol present in Symbol
	 */
	public int getNumberOfSymbolG() {
		return numberOfSymbolG;
	}

	public String getSymbolG(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.G) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
	
	/**
	 * @return The number of left bracket symbol present in Symbol
	 */
	public int getNumberOfSymbolK() {
		return numberOfSymbolK;
	}

	public String getSymbolK(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.K) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
	
	/**
	 * @return The number of right bracket symbol present in Symbol
	 */
	public int getNumberOfSymbolL() {
		return numberOfSymbolL;
	}

	public String getSymbolL(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.L) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
	
	/**
	 * @return The number of mode symbol present in Symbol
	 */
	public int getNumberOfSymbolM() {
		return numberOfSymbolM;
	}

	public String getSymbolM(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.M) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
		
	/**
	 * @return The number of functor symbol present in Symbol
	 */
	public int getNumberOfSymbolO() {
		return numberOfSymbolO;
	}
	
	public String getSymbolO(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.O) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
		
	/**
	 * @return The number of predicate symbol present in Symbol
	 */
	public int getNumberOfSymbolR() {
		return numberOfSymbolR;
	}
	
	public String getSymbolR(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.R) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
	
	/**
	 * @return The number of selector symbol present in Symbol
	 */
	public int getNumberOfSymbolU() {
		return numberOfSymbolU;
	}
	
	public String getSymbolU(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.U) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}
	
	/**
	 * @return The number of attribute symbol present in Symbol
	 */
	public int getNumberOfSymbolV() {
		return numberOfSymbolV;
	}

	public String getSymbolV(int nr) {
		for (Symbol symbol : symbolList){
			if (symbol.getSymbolType() == SymbolKind.V) nr--;
			if (nr == 0) return symbol.getSymbolToken();
		}
		return null;
	}

	@Override
	public String toString() {
		String ret = SystemHost.lineTerminator;
		StringBuffer sb = new StringBuffer("");
		sb.append("#"+articleId);
		sb.append(ret);
		sb.append("G"+numberOfSymbolG+" ");
		sb.append("K"+numberOfSymbolK+" ");
		sb.append("L"+numberOfSymbolL+" ");
		sb.append("M"+numberOfSymbolM+" ");
		sb.append("O"+numberOfSymbolO+" ");
		sb.append("R"+numberOfSymbolR+" ");
		sb.append("U"+numberOfSymbolU+" ");
		sb.append("V"+numberOfSymbolV+" ");
		for (Symbol s : symbolList){
			sb.append(ret);
			sb.append(s.toString());
		};
		return sb.toString();
	}

	public ArrayList<Symbol> getSymbolList() {
		return symbolList;
	}

	public String toStringInFile() {
		String ret = SystemHost.lineTerminator;
		StringBuffer sb = new StringBuffer("");
		sb.append("#"+articleId);
		sb.append(ret);
		sb.append("G"+numberOfSymbolInFileG+" ");
		sb.append("K"+numberOfSymbolInFileK+" ");
		sb.append("L"+numberOfSymbolInFileL+" ");
		sb.append("M"+numberOfSymbolInFileM+" ");
		sb.append("O"+numberOfSymbolInFileO+" ");
		sb.append("R"+numberOfSymbolInFileR+" ");
		sb.append("U"+numberOfSymbolInFileU+" ");
		sb.append("V"+numberOfSymbolInFileV+" ");
		for (Symbol s : symbolList){
			if (!s.isSyntaxToken()){
				sb.append(ret);
				sb.append(s.toString());
			}
		};
		return sb.toString();
	}
	
}
